home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
316_01
/
as8.c
< prev
next >
Wrap
Text File
|
1990-05-14
|
32KB
|
1,683 lines
/*
* z8 assembler hgw july 1983: h.-g. willers
*
* register syntax:
* register: r0 - r127, r240 - r255
* working register: w0 - w15
*
*/
#include <stdio.h>
#include <setjmp.h>
#define NCPS 33 /* number of characters per symbol */
#define NCPLE NCPS+2 /* number of characters per listing element */
#define NLEPL 1 /* number of listing elements per line */
#define NBIN 32
#define NTSYM 512 /* length of numeric-label table */
#define NERR 10
#define NINPUT 128
#define NCODE 128
#define NTIT 64
#define HASHSIZ 503 /* hashtable size */
/* must be prime */
/* more primes: */
/* 503, 607, 701, 809, 907, 1009 */
/* see: handbook of math. functions p. 879 */
#define NLIST 0
#define SLIST 1
#define ALIST 2
#define CLIST 3
typedef unsigned addr_t;
struct sym
{
char *s_name;
char s_type;
char s_flag;
addr_t s_addr;
};
#define S_UND 0
#define S_ABS 1
#define S_OP0 2
#define S_OP2 4
#define S_OP3 5
#define S_OP4 6
#define S_OP5 7
#define S_OP6 8
#define S_OP7 9
#define S_OP8 10
#define S_OP9 11
#define S_OP10 12
#define S_OP11 13
#define S_OP12 14
#define S_OP13 15
#define S_OP14 16
#define S_OP15 17
#define S_LIT 19
#define S_REG 20
#define S_WREG 21
#define S_IR 22 /* register indirect */
#define S_WIR 23 /* working register indirect */
#define S_INDEX 24
#define S_WORD 25
#define S_ASCII 26
#define S_ASCIZ 27
#define S_BLKB 28
#define S_PAGE 29
#define S_TITLE 30
#define S_BYTE 31
#define S_HLIST 32
#define S_OLIST 33
#define S_INTEL 34
#define S_MKBUG 35
#define S_LIST 36
#define S_NLIST 37
#define S_START 38
#define WRMASK 0xe0 /* msbs for working reg. add. */
#define CALL 0xd6 /* direct call */
#define CALLI 0xd4 /* indirect call */
#define SOB 0x0a /* sob-instruction */
#define JUMP 0x8d /* jump-always instruction */
#define JUMPI 0x30 /* jump indirect */
#define SRP 0x31
#define INCW 0x0e /* inc working register */
#define S_MDF 01 /* Mult. def */
#define S_ASG 02 /* Assigned def */
struct tsym
{
int t_num;
addr_t t_addr;
};
struct tsymp
{
struct tsym *t_fp;
struct tsym *t_bp;
};
struct addr
{
char a_type;
char a_reg;
addr_t a_addr;
};
int line;
int page;
int lop;
int pass;
int ntsym;
int sflag = 0; /* symbol-table-flag */
int lflag;
int nflag;
int eflag;
addr_t laddr;
int lmode;
int ldis = 0; /* listing disable */
/* =1 listing is disabled */
int hlist = 1; /* hex listing is default */
int ninst = 0; /* number of installs into symbol table */
char *ep;
char eb[NERR];
char *ip;
char ib[NINPUT];
char *cp;
char cb[NCODE];
char tb[NTIT];
int bo;
int ba;
char bb[NBIN];
unsigned int startadr = 0xffff; /* start address */
char liname[80];
char obname[80]; /* listing and object filenames */
char stbnam[80];
jmp_buf env;
long daytime;
long time();
char *ctime();
char *malloc();
struct sym *lookup();
struct sym *addr1();
struct sym *dot; /* pointer to . value into symbol table */
struct sym sym[HASHSIZ] = {0}; /* space for symbol table */
extern struct sym optab[];
struct tsym tsym[NTSYM];
struct tsymp tsymp[10];
/* lower opcode nibbles for class-8 opcodes */
/* ordered as follows: destination, source, nibble */
/* table ends at zero destination */
char c8nib[] = { S_WREG, S_WREG, 2,
S_WREG, S_WIR, 3,
S_WREG, S_WREG, 4,
S_WREG, S_REG, 4,
S_REG, S_WREG, 4,
S_REG, S_REG, 4,
S_WREG, S_WIR, 5,
S_WREG, S_IR, 5,
S_REG, S_WIR, 5,
S_REG, S_IR, 5,
S_WREG, S_LIT, 6,
S_REG, S_LIT, 6,
S_WIR, S_LIT, 7,
S_IR, S_LIT, 7,
0, 0, 0
};
char movtab[] = { S_WREG, S_LIT, 0x0c,
S_WREG, S_REG, 0x08,
S_WREG, S_WREG, 0x08,
S_REG, S_WREG, 0x09,
S_WREG, S_INDEX, 0xc7,
S_INDEX, S_WREG, 0xd7,
S_WREG, S_WIR, 0xe3,
S_WIR, S_WREG, 0xf3,
S_REG, S_REG, 0xe4,
S_REG, S_IR, 0xe5,
S_REG, S_LIT, 0xe6,
S_IR, S_LIT, 0xe7,
S_IR, S_REG, 0xf5,
S_WIR, S_REG, 0xf5,
S_IR, S_WREG, 0xf5,
S_WIR, S_WREG, 0xf5,
0, 0, 0
};
char c13tab[] = {S_WREG, S_WIR, 1,
S_WIR, S_WREG, 2,
0, 0, 0
};
FILE *lfp;
FILE *ofp;
FILE *sfp;
char *strrchr();
char *strchr();
main(argc, argv)
char *argv[];
{
register char *p;
register c, i;
struct tsym *tp;
char *iptr; /* index-pointer */
char *fn;
FILE *afile();
fn = NULL;
for (i=1; i<argc; ++i) {
p = argv[i];
if (*p == '-') {
++p;
while (c = *p++)
switch(c) {
case 'l':
case 'L':
++lflag;
break;
case 'n':
case 'N':
++nflag;
break;
default:
fprintf(stderr, "%c: ignored.\n", c);
}
} else
fn = p;
}
if (fn != NULL) {
sfp = afile(fn, 0);
if((iptr = strrchr(fn, '/')) == NULL)
strcpy(liname, fn);
else
strcpy(liname, ++iptr);
if((iptr = strrchr(liname, '.')) != NULL)
*iptr = 0; /* truncate suffix (if any) */
if (!nflag) {
strcpy(obname, liname);
strcat(obname, ".o");
}
if (lflag) {
strcat(liname, ".l");
lfp = afile(liname, 1);
}
if(strcmp (fn, obname) == 0) {
fprintf(stderr, "Would overwrite %s\n", fn);
exit(1);
}
ofp = afile(obname, 1);
for (pass=0; pass<2; ++pass) {
if(pass == 0)
insopc(); /* install opcodes */
dot = lookup(".", 0, 0); /* locate . in table */
dot->s_type = S_ABS;
dot->s_flag = S_ASG;
dot->s_addr = 0;
line = 0;
page = 1;
lop = 60;
if (pass == 1) {
rewind(sfp);
for (i=0; i<10; ++i) {
tsymp[i].t_fp = NULL;
tsymp[i].t_bp = NULL;
tp = tsym;
while (tp < &tsym[ntsym]) {
if (tp->t_num == i) {
tsymp[i].t_fp = tp;
break;
}
++tp;
}
}
}
while (fgets(ib, sizeof ib, sfp) != NULL) {
iptr = strchr(ib,'\n');
*iptr = 0;
++line;
cp = cb;
ep = eb;
ip = ib;
eflag = 0;
setjmp(env);
if (eflag == 0)
xasm();
if (pass == 1) {
diag();
list();
}
}
}
if (!nflag) {
bflush();
beof();
}
prstb();
prstat();
}
}
FILE *
afile(fn, wf)
char *fn;
{
register FILE *fp;
fp = fopen(fn, wf?"w":"r");
if (fp == NULL) {
fprintf(stderr, "%s: cannot open.\n", fn);
exit(1);
}
return (fp);
}
xasm()
{
register c;
register addr_t a;
struct sym *sp;
struct tsym *tp;
int b, d, op;
char *p, id[NCPS];
struct addr a1, a2;
laddr = dot->s_addr;
lmode = SLIST;
loop:
while ((c = getnb()) == ';')
;
if (c == 0 || c == '/')
return;
if (isdigit(c)) {
if (getnb() != ':')
err('q');
c -= '0';
if (pass == 0) {
if (ntsym >= NTSYM)
error("Too many temp. symbols!\n");
tsym[ntsym].t_num = c;
tsym[ntsym].t_addr = dot->s_addr;
++ntsym;
}
else {
tp = tsymp[c].t_fp;
tsymp[c].t_bp = tp;
tsymp[c].t_fp = NULL;
++tp;
while (tp < &tsym[ntsym]) {
if (tp->t_num == c) {
tsymp[c].t_fp = tp;
break;
}
++tp;
}
}
goto loop;
}
if (!isidc(c))
err('q');
getid(c, id);
if ((c = getnb()) == ':') {
sp = lookup(id, 1, 0);
if (pass == 0) {
if (sp->s_type!=S_UND && (sp->s_flag&S_ASG)==0)
sp->s_flag |= S_MDF;
sp->s_type = S_ABS;
sp->s_addr = dot->s_addr;
} else {
if ((sp->s_flag&S_MDF) != 0)
err('m');
if (sp->s_type!=S_ABS || sp->s_addr!=dot->s_addr)
err('p');
}
lmode = ALIST;
goto loop;
}
if (c == '=') {
sp = lookup(id, 1, 0);
if (sp->s_type!=S_UND && (sp->s_flag&S_ASG)==0)
err('m');
expr(&a1);
sp->s_addr = laddr = a1.a_addr;
sp->s_flag = S_ASG;
sp->s_type = a1.a_type;
lmode = ALIST;
goto loop;
}
unget(c);
lmode = CLIST;
if ((sp=lookup(id, 0, 0)) == NULL) {
err('o');
return;
}
op = sp->s_addr;
switch(sp->s_type) {
case S_HLIST:
case S_OLI